// -----------------------------------------------------------------------
//  <copyright file="PickupIntegrationEventInterceptor.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/23 21:34</last-date>
// -----------------------------------------------------------------------

using Microsoft.EntityFrameworkCore.Diagnostics;

namespace DaprPlus.EntityFrameworkCore;

/// <summary>
/// 保存前提取实体中的集成事件拦截器
/// </summary>
public class PickupIntegrationEventInterceptor(IServiceProvider provider) : SaveChangesInterceptor
{
    public override int SavedChanges(SaveChangesCompletedEventData eventData, int result)
    {
        PickupIntegrationEvents(eventData.Context);
        return base.SavedChanges(eventData, result);
    }

    public override ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,
        CancellationToken cancellationToken = default)
    {
        PickupIntegrationEvents(eventData.Context);
        return base.SavedChangesAsync(eventData, result, cancellationToken);
    }

    private void PickupIntegrationEvents(DbContext? context)
    {
        if (context == null)
        {
            return;
        }
        var integrationEntities = context.ChangeTracker.Entries<IHasIntegrationEvent>()
            .Select(m => m.Entity).Where(n => n.IntegrationEvents.Count > 0).ToList();
        if (integrationEntities.Count == 0)
        {
            return;
        }
        var uow = provider.GetUnitOfWork();
        foreach (var entity in integrationEntities)
        {
            if (entity.IntegrationEvents.Count == 0)
            {
                continue;
            }
            var events = entity.IntegrationEvents.ToArray();
            entity.ClearIntegrationEvents();
            uow.AddIntegrationEvent(events);
        }
    }
}
